// 登录拦截，没有路由守卫这个东西，需要拦截的话，可以自己去封装 Route

import React from "react";
import ReactDOM from "react-dom";
import {
  HashRouter as Router,
  Route,
  Link,
  Redirect,
  withRouter
} from "react-router-dom";

////////////////////////////////////////////////////////////
// 1. Click the public page
// 2. Click the protected page
// 3. Log in
// 4. Click the back button, note the URL each time
////////////////////////////////////////////////////////////

const fakeAuth = {
  // fakeAuth登录的对象集合
  isAuthenticated: false, // 登录状态

  // 登录方法
  authenticate(cb) {
    this.isAuthenticated = true;
    setTimeout(cb, 100); // fake async
  },

  // 退出登录方法
  signout(cb) {
    this.isAuthenticated = false;
    setTimeout(cb, 100);
  }
};

const AuthExample = () => (
  <Router>
    <div>
      <AuthButton />
      <ul>
        <li>
          <Link to="/public">公共页面</Link>
        </li>
        <li>
          <Link to="/protected">需要登录验证的页面</Link>
        </li>
        {/* <Link to={{ pathname: '/login', state: { from: { pathname: '/abc' } } }}>登录页面</Link> */}
      </ul>

      <Route path="/public" component={Public} />
      <Route path="/login" component={Login} />
      {/* PrivateRoute 自定义 的路由组件实现路由拦截功能  通过将props,path="/protected" component={Protected}传过去*/}
      <PrivateRoute path="/protected" component={Protected} />
    </div>
  </Router>
);

// withRouter 方法重新包装router
const AuthButton = withRouter(({ history }) =>
  // 登录状态 登录了就显示退出, 没有登录就显示没有登录
  fakeAuth.isAuthenticated ? (
    <p>
      Welcome!{" "}
      <button
        onClick={() => {
          //  函数式路由跳转
          fakeAuth.signout(() => history.push("/"));
        }}
      >
        退出登录
      </button>
    </p>
  ) : (
      <p>You are not logged in.</p>
    )
);

// 自己对 Route 组件做的一个封装。（高阶组件）
// props.path
// props.component

// rest = { path: '/protected' }
// 自己定义的一个Router组件,来实现路由拦截功能
// component: Component,将props中的component解构赋值出来并且实施重命名,应为下面是要作为组件使用
// ...rest 是接受剩下的元素
const PrivateRoute = ({ component: Component, ...rest }) => (
  <Route
    // 这是在路由中将剩余的props元素展开
    {...rest} // 里面有路径 和路由页面的三props属性
    render={
      //这里的props是路由三prop
      (props) =>
        // 登录对象集合中的登录状态
        fakeAuth.isAuthenticated ? (
          // 为true 就显示该组件
          <Component {...props} />
        ) : (
            <Redirect
              // 登录状态为false时重定向到登录页面
              to={{
                pathname: "/login",
                state: { from: props.location }
              }}
            />
          )
    }
  />
);

const Public = () => <h3>公共页面</h3>;
const Protected = () => <h3>需要登录的页面</h3>;

//登录页面
class Login extends React.Component {
  state = {
    // 登录状态
    redirectToReferrer: false
  };

  login = () => {
    // 点击登录时触发登录方法
    fakeAuth.authenticate(() => {
      // 将redirectToReferrer登录状态转变为true
      this.setState({ redirectToReferrer: true });
    });
  };

  render() {
    // 解构赋值到 from  有传递过来想去的页面就去这个页面   没有的话就去 /
    const { from } = this.props.location.state || { from: { pathname: "/" } };
    const { redirectToReferrer } = this.state;

    // 如果登录状态为true 就重定向到from页面
    if (redirectToReferrer) {
      return <Redirect to={from} />;
    }

    return (
      <div>
        <p>你还没有权限需要先登录 {from.pathname}</p>
        <button onClick={this.login}>登录</button>
      </div>
    );
  }
}

export default AuthExample;
// ReactDOM.render(<AuthExample />, document.getElementById('root'))
